﻿/********************************************************************************
    Copyright (C) Binod Nepal, Planet Earth Solutions Pvt. Ltd., Kathmandu.
	Released under the terms of the GNU General Public License, GPL, 
	as published by the Free Software Foundation, either version 3 
	of the License, or (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
    See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
***********************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Transactions;

namespace MixNP.Web.Classifieds.Account
{
    public partial class Recover : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string token = Pes.Utility.Conversion.TryCastString(RouteData.Values["token"]);
            
            if (string.IsNullOrWhiteSpace(token))
            {
                NotificationPanel.Visible = false;
                EmailRecoveryPanel.Visible = false;
                TextRecoveryPanel.Visible = true;
            }
            else
            {
                if (!MixNP.BusinessLayer.Users.IsValidRecoveryCode(token))
                {
                    Pes.Utility.PageUtility.InvalidPasswordAttempts(this.Page, 1);
                    Response.Redirect("~/access-denied.mix");
                    return;
                }

                NotificationPanel.Visible = false;
                EmailRecoveryPanel.Visible = true;
                TextRecoveryPanel.Visible = false;            
            }

            MixNP.Web.ServiceLayer.ControlManager.AddTextBox("RecoveryCodeTextBox", "Recovery Code", string.Empty, 6, double.MinValue, true, string.Empty, "textbox wide", "Type the recovery code we sent on your phone.", string.Empty, false, 100, this.Page, placeHolder);
            MixNP.Web.ServiceLayer.ControlManager.AddTextBox("EmailAddressTextBox", "Your Email Address", string.Empty, 128, double.MinValue, true, string.Empty, "textbox wide", "Provide your account email address.", string.Empty, false, 100, this.Page, placeHolder);
        }

        protected void RecoverButton2_Click(object sender, EventArgs e)
        {
            string recoveryCode = Pes.Utility.Conversion.TryCastString(RouteData.Values["token"]);
            string newPassword = PasswordTextBox2.Text;
            string confirmPassword = ConfirmPasswordTextBox2.Text;
            string emailAddress = MixNP.BusinessLayer.Users.GetEmailAddressFromRecoveryCode(recoveryCode);

            if (!newPassword.Equals(confirmPassword))
            {
                ErrorLiteral2.Text = "<div class='alert'>Passwords do not match.</div>";
                return;
            }

            if (!MixNP.BusinessLayer.Users.IsValidRecoveryCode(recoveryCode))
            {
                ErrorLiteral2.Text = "<div class='alert'>Invalid recovery code.</div>";
                return;
            }


            string newPasswordSalt = Guid.NewGuid().ToString();
            string newHashedPassword = Pes.Utility.Conversion.HashSha512(confirmPassword, newPasswordSalt);

            var transactionOptions = new TransactionOptions();
            transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
            transactionOptions.Timeout = TransactionManager.MaximumTimeout;

            try
            {

                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
                {
                    if (MixNP.BusinessLayer.Users.ChangePassword(emailAddress, newHashedPassword, newPasswordSalt))
                    {
                        if (MixNP.BusinessLayer.Users.FlagRecoveryCode(recoveryCode))
                        {
                            scope.Complete();
                            NotificationPanel.Visible = true;
                            EmailRecoveryPanel.Visible = false;
                            TextRecoveryPanel.Visible = false;
                        }
                    }
                }
            }
            catch
            {
                //Todo: Notify the user that the recovery was unsuccessful.
                throw;
            }
        
        }

        protected void RecoverButton_Click(object sender, EventArgs e)
        {
            string recoveryCode = MixNP.BusinessLayer.Helpers.RequestForm.GetUserControlFormValue("RecoveryCodeTextBox", this.Page);
            string emailAddress = MixNP.BusinessLayer.Helpers.RequestForm.GetUserControlFormValue("EmailAddressTextBox", this.Page);
            string newPassword = PasswordTextBox.Text;
            string confirmPassword = ConfirmPasswordTextBox.Text;

            if (!newPassword.Equals(confirmPassword))
            {
                ErrorLiteral.Text = "<div class='alert'>Passwords do not match.</div>";
                return;
            }

            if (!MixNP.BusinessLayer.Users.IsValidRecoveryCode(recoveryCode, emailAddress))
            {
                ErrorLiteral.Text = "<div class='alert'>Invalid recovery code.</div>";
                return;
            }


            string newPasswordSalt = Guid.NewGuid().ToString();
            string newHashedPassword = Pes.Utility.Conversion.HashSha512(confirmPassword, newPasswordSalt);

            var transactionOptions = new TransactionOptions();
            transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
            transactionOptions.Timeout = TransactionManager.MaximumTimeout;

            try
            {

                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
                {
                    if (MixNP.BusinessLayer.Users.ChangePassword(emailAddress, newHashedPassword, newPasswordSalt))
                    {
                        if (MixNP.BusinessLayer.Users.FlagRecoveryCode(recoveryCode, emailAddress))
                        {
                            scope.Complete();
                            NotificationPanel.Visible = true;
                            EmailRecoveryPanel.Visible = false;
                            TextRecoveryPanel.Visible = false;
                        }
                    }
                }
            }
            catch
            {
                //Todo: Notify the user that the recovery was unsuccessful.
                throw;
            }

        }

    }
}